package puppy.graph;

import java.awt.Dimension;
import java.util.Enumeration;
import java.util.HashSet;
import java.util.Hashtable;

import java.util.regex.Pattern;

import javax.swing.JFrame;



import puppy.query.QueryNGramExtractor;

import util.io.FileInput;

import util.string.URLCleaner;

import edu.uci.ics.jung.algorithms.layout.CircleLayout;
import edu.uci.ics.jung.algorithms.layout.Layout;
import edu.uci.ics.jung.graph.Graph;
import edu.uci.ics.jung.graph.UndirectedSparseGraph;
import edu.uci.ics.jung.visualization.BasicVisualizationServer;
import edu.uci.ics.jung.visualization.decorators.ToStringLabeller;


import fileloaders.mallet.MalletTopicsProbs;
import fileloaders.parsers.InLineParser;

public class CreateGraphDirected {

	private static final Integer EDGE_THRESHOLD = 3;
	private static final Integer NODE_THRESHOLD = 3;
	
	
	private static final Integer EDGE_THRESHOLD_KIDS = 2;
	private static final Integer NODE_THRESHOLD_KID = 3;
	
	float threshold_d=0.014f;
	float threshold_w=0.0001f;//0.01f;
	
	
	/**
	 * @param args
	 */
	public int n_nodes = 0;
	public int n_edges = 0;

	// Generate
	// id_url, id_tag, url,tag,freq_tag,freq_url, freq_ut,type
	
	
	//http://5.ua/	tv_news	adults	11953	10	3	5.ua

	
	public UndirectedSparseGraph<DeliciousNode, DeliciousEdge> graph1= null;
	
	
	public Graph<DeliciousNode, DeliciousEdge> subgraph=null;
	
	private Pattern tab = Pattern.compile("\t");
	public Hashtable<String,String> urls_simplified = new  Hashtable<String,String> ();
	
	public QueryNGramExtractor query_phraser = new QueryNGramExtractor();
	public Hashtable<String, DeliciousNode> nodes = new Hashtable<String, DeliciousNode>();

	AgeAggregator agg= null;

	/**
	 * Topic fields
	 * 
	 * 
	 * 
	 */
	//TODO change this
	public Hashtable<String,Hashtable<Short,Float>> w_topics= new  Hashtable<String,Hashtable<Short,Float>>();
	
	public Hashtable<String,Hashtable<Short,Float>> topics_docs= new  Hashtable<String,Hashtable<Short,Float>>();
	public Hashtable<String,Float> z_probs = new Hashtable<String,Float> ();
	
	public void initTopics(String w_p, String d_p, String z_path){
		
		if(w_p!=null && d_p!=null){
		MalletTopicsProbs.loadTopicGivenDoc(d_p, topics_docs);
		MalletTopicsProbs.loadTopicGivenWord(w_p, w_topics);
		}
		
		
		MalletTopicsProbs.loadTopicProbs(z_path, z_probs);
		
	}
	
	private boolean createTopicNodes=false;
	public  Hashtable<String, HashSet<String>> ages =new Hashtable<String,HashSet<String>>();
	public CreateGraphDirected(AgeAggregator agg, String w_p, String d_p,String z_p){
		
		this.agg=agg;
	
		if(w_p!=null && d_p!=null && z_p !=null){
			
			initTopics(w_p,d_p,z_p);
			createTopicNodes=true;
		}
	}
	
	public void initGraph(String path) {

		FileInput in = new FileInput(path);
		graph1 = new UndirectedSparseGraph<DeliciousNode, DeliciousEdge>();
		
		
		String line = in.readString();
		
		int j =0;
		while (line != null) {
		//	System.out.println("Adding " + line);
			dumpLineIntoGraphDirected(graph1, line);
			line = in.readString();
			j++;
	//	if(j==5) return;
		}
	}


	public void aggreageteValueInHash(Hashtable<String,Integer>h, String key, int value){
		
		if(h.containsKey(key)){
			
			h.put(key, h.get(key)+ value);
			
		}else{
			
			h.put(key, value);
			
		}
		
	}
	
	private void dumpLineIntoGraphDirected(
			UndirectedSparseGraph<DeliciousNode, DeliciousEdge> graph,
			String line) {
		
		String[] fields =  tab.split(line);

		//System.out.println(line);
		line =null;
		Hashtable<String, Object> f = InLineParser.parseGraphEnrichedLine(fields,agg,ages ,nodes);
		
		
		if(f==null) return;
		
		
		String[] url_tag=  (String[]) f.get("keys");

		f.remove("keys");
	
		
		DeliciousNode url=null;
		DeliciousNode tag=null;
	
	
		
		url = nodes.get(url_tag[0]);
		
		tag= nodes.get(url_tag[1]);
			
		DeliciousEdge edge =null;
		Float freq_ut= (Float) f.get("freq_ut");
		
		
		/*
		 * Adding url node
		 */
	
		 String simple =URLCleaner.simplifyURL(url_tag[0],1);
		
			 urls_simplified.put(simple,url_tag[0]);
					
		//	aggreageteValueInHash(urls_totals,age, freq_url);	
		//create edge
		
		edge = new DeliciousEdge();
		edge.tag=tag;
		edge.url=url;
		edge.setProb(freq_ut);
		
	
	
	if (tag != null && url != null) {
		graph.addVertex(tag);
		graph.addVertex(url);
		graph.addEdge(edge, url, tag);
		
		
		
		if(createTopicNodes){
		createTopicLinks(tag, threshold_d, threshold_w);
	//	createTopicLinks(url, threshold_d, threshold_w);
		}
		
		
	}
	
	
	
	}
	
	public void createTopicLinks(DeliciousNode a, float threshold_d,  float threshold_w){
	
		
		if(!a.isTag()){
			
			 String simple =URLCleaner.simplifyURL(a.getName(),1);
			 Hashtable<Short, Float> topics=null;
			
				 topics = topics_docs.get(simple);
		
			Enumeration<Short> keys = topics.keys();
			
			while(keys.hasMoreElements()){
				
				Short topic = keys.nextElement();
				Float z_doc= topics.get(topic);
				
				Float prob_topic = z_probs.get("t-"+topic);

				if(z_doc>threshold_d){
					String name ="t-"+ String.valueOf(topic);
					DeliciousNode z =null;
					if(nodes.containsKey(name)){
						z= nodes.get(name);
					}else{
						z= new DeliciousNode();
						
					}
				
					if(nodes.containsKey(name)){
						z = new DeliciousNode();
					}
					else{
						z= new DeliciousNode();
					}
					
				//	System.out.println("Adding link:" + name + "\t"+ a.getName()  + "\t"+ prob);
					z.setName(name);
					z.setProb(prob_topic);
					
					
				//	System.out.println("adding  " + a.getName() + "\t"+ z.getName() + "\t"+  z_doc);
				//	graph1.addVertex(z);
					DeliciousEdge edge= new DeliciousEdge();
					edge.url= a;
					edge.tag=z;
					edge.setProb(z_doc);
					
					nodes.put(z.getName(), z);

					graph1.addEdge(edge, a, z);
					
					
			}
		  }
		}
		
		else{
			//System.out.println(a.getName());
			Hashtable<Short, Float> topics = w_topics.get(a.getName());
			if(topics==null) return;
			Enumeration<Short> keys = topics.keys();
			
			while(keys.hasMoreElements()){
				
				Short topic = keys.nextElement();
				
				Float z_prob = z_probs.get(new String("t-"+ topic));
				Float z_tag= topics.get(topic);

				if(z_tag>threshold_w){
					
					//create adge url --> z 
					
					String name ="t-" + String.valueOf(topic); 
					DeliciousNode z = null;
					
					
					
					if(nodes.containsKey(name)){
						z= nodes.get(name);
					
						
					}else{
						z= new DeliciousNode();
						z.setName(name);
						z.setTopic(true);
						z.setProb(z_prob);
						nodes.put(z.getName(), z);	
					}
				//	System.out.println("adding  " + a.getName() + "\t"+ z.getName() + "\t"+ z_tag);
					
					
					graph1.addVertex(z);
					DeliciousEdge edge= new DeliciousEdge();
					edge.url= z;
					edge.setProb(z_tag);
					edge.tag=a;
					graph1.addEdge(edge, a, z);
					
					
			}
		  }
			
			
			
		}
		
		
		
	}
	
	
	public void displayGraph(){
		
		Layout<Integer, String> layout = new CircleLayout(graph1);
		System.out.println(graph1.getEdges().size());
	    layout.setSize(new Dimension(300,300)); // sets the initial size of the space
	     // The BasicVisualizationServer<V,E> is parameterized by the edge types
	     BasicVisualizationServer<Integer,String> vv =
	              new BasicVisualizationServer<Integer,String>(layout);
	     vv.setPreferredSize(new Dimension(350,350)); //Sets the viewing area size
	        vv.getRenderContext().setVertexLabelTransformer(new ToStringLabeller());

	    
	     
	     JFrame frame = new JFrame("Simple Graph View");
	     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
	     frame.getContentPane().add(vv);
	     frame.pack();
	     frame.setVisible(true);
		
	}
	

/*	
	
	public void createGraph1(){
		

		*//** add nodes 
		 * 
		 * 
		 *//*
	
			DeliciousNode node = new DeliciousNode();
			
			node.setId(1);
			node.setName("A");
			
			DeliciousNode node1 = new DeliciousNode();
			node1.setId(2);
			node1.setName("B");
			
			DeliciousEdge edge =  new DeliciousEdge();
		
			graph.addEdge(edge, node, node1);
		
		
	}*/

	

}